# -*- coding:utf-8 -*-
"""
Created on 2017年11月24日
update time: 2017年11月24日
@author: nice丶柠檬
content: 微信调起请求， 微信签名验证，返回回调地址处理
"""
from app import util, redis
import time
import hashlib
import urllib2
import xml2dict
import datetime

cookies = urllib2.HTTPCookieProcessor()
opener = urllib2.build_opener(cookies)
app_id = "wx087bed01c194a785"
partner_id = "1455204902"
keys = "72fd9810cb88f6ecc6ad617fa6d23033"
code_error = "<xml><return_code>FAIL</return_code><return_msg>ERROR</return_msg></xml>"
code_success = "<xml> <return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"


# 向官方进行发起支付请求
def client_send(return_url, order_num, client_ip, money, uid, plateNum, machineId):
    create_time = int(time.time())
    print return_url
    try:
        nonce_str = util.md5(str(time.time()) + str(uid))
        md5 = "appid=" + app_id + "&body=vip&mch_id=" + partner_id + "&nonce_str=" + nonce_str + "&notify_url=" + \
              return_url + "&openid=" + uid + "&out_trade_no=" + order_num + "&spbill_create_ip=" + client_ip + "&total_fee=" + money \
              + "&trade_type=JSAPI&key=" + keys
        m1 = hashlib.md5()
        m1.update(md5)
        key = m1.hexdigest().upper()
        xml = "<xml><appid>wx087bed01c194a785</appid>" + \
              "<body>vip</body>" + \
              "<mch_id>" + partner_id + "</mch_id>" + \
              "<nonce_str>" + nonce_str + "</nonce_str>" + \
              "<notify_url>" + return_url + "</notify_url>" + \
              "<openid>" + uid + "</openid>" + \
              "<out_trade_no>" + order_num + "</out_trade_no>" + \
              "<spbill_create_ip>" + client_ip + "</spbill_create_ip>" + \
              "<total_fee>" + money + "</total_fee>" + \
              "<trade_type>JSAPI</trade_type>" + \
              "<sign>" + key + "</sign></xml>"
        request = urllib2.Request(url="https://api.mch.weixin.qq.com/pay/unifiedorder",
                                  headers={'Content-Type': 'application/xml', 'charset': 'UTF-8'},
                                  data=xml)
        f = opener.open(request)
        data = f.read()
        data = xml2dict.xml2dict(data)
        print data
        if data['return_code']['_text'] == 'SUCCESS':
            code = 200
            prepay_id = data['prepay_id']['_text']
            nonce_str = data['nonce_str']['_text']
            sign = sign_create(prepay_id, nonce_str, str(create_time))
            data_detail = {
                'total_fee': money,
                'orderNum': order_num,
                'orderTime': datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
                'status': 0,
                'plateNum': plateNum,
                'machineId': machineId
            }
            key = "machine_pay_data_" + datetime.datetime.today().strftime('%Y-%m-%d')
            redis.hset(key, order_num, data_detail)
            redis.expire(key, 86400)
            appId = app_id
        else:
            prepay_id = ''
            nonce_str = ''
            appId = ""
            sign = ''
            code = 400
        data = {
            "prepay_id": prepay_id,
            "nonce_str": nonce_str,
            "sign": sign,
            "code": code,
            "create_time": create_time,
            'appId': appId
        }
    except Exception as e:
        print e
        data = {
            "prepay_id": '',
            "nonce_str": '',
            "sign": '',
            "code": 500,
            "create_time": create_time,
            "appId": ""
        }
    return data


# 调起后生成签名
def sign_create(prepay_id, nonce_str, timestamp):
    md5s = "appId=" + app_id + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + \
           "&signType=MD5" + "&timeStamp=" + timestamp + "&key=" + keys
    sign = util.md5(md5s).upper()
    return sign


# 微信回调地址处理
def api_wx_return(data):
    data = xml2dict.xml2dict(data)
    # 支付状态失败，返回失败
    if data['result_code']['_text'] == "FAIL":
        return code_error
    # 验证APP_ID还有商户ID是否一致
    if app_id != data['appid']['_text'] or partner_id != data['mch_id']['_text']:
        return code_error
    params = {}
    sign = ''
    for xml in data:
        if xml == "sign":
            sign = data[xml]['_text']
        else:
            params[xml] = data[xml]['_text']
    # 检测是否含有签名
    if sign == '':
        return code_error
    params_keys = params.keys()
    params_keys.sort()
    md5s = ''
    for x in params_keys:
        md5s += x + "=" + params.get(x) + "&"
    md5s = md5s + "key=" + keys
    # 计算签名是否一致，不一致返回错误
    if sign != util.md5(md5s).upper():
        return code_error
    # 检测订单是否一致
    out_trade_no = data['out_trade_no']['_text'].split('_')
    if len(out_trade_no) != 4:
        return code_error
    key = "machine_pay_data_" + datetime.datetime.today().strftime('%Y-%m-%d')
    result = redis.hget(key, data['out_trade_no']['_text'])
    result = eval(result)
    data_detail = {
        'total_fee': data['total_fee']['_text'],
        'orderNum': out_trade_no,
        'orderTime': result['orderTime'],
        'plateNum': result['plateNum'],
        'machineId': result['machineId'],
        'status': 1,
    }
    redis.hset(key, data['out_trade_no'], data_detail)
    redis.expire(key, 86400)
    key1 = "machine_pay_" + datetime.datetime.today().strftime('%Y-%m-%d')
    data_push = {
        "wx_order": data['transaction_id']['_text'],
        "good_order": data['out_trade_no']['_text'],
        "pay_time": datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
        "order_time": result['orderTime'],
        'plateNum': result['plateNum'],
        "uid": out_trade_no[0],
        'store_id': out_trade_no[1],
        "flag": out_trade_no[2],
        "money": data['total_fee']['_text'],
        'machineId': result['machineId'],
    }
    redis.rpush(key1, data_push)
    redis.expire(key1, 86400)
    return code_success


# 微信商家购买回调地址处理
def api_wx_business_return(data):
    data = xml2dict.xml2dict(data)
    # 支付状态失败，返回失败
    if data['result_code']['_text'] == "FAIL":
        return code_error
    # 验证APP_ID还有商户ID是否一致
    if app_id != data['appid']['_text'] or partner_id != data['mch_id']['_text']:
        return code_error
    params = {}
    sign = ''
    for xml in data:
        if xml == "sign":
            sign = data[xml]['_text']
        else:
            params[xml] = data[xml]['_text']
    # 检测是否含有签名
    if sign == '':
        return code_error
    params_keys = params.keys()
    params_keys.sort()
    md5s = ''
    for x in params_keys:
        md5s += x + "=" + params.get(x) + "&"
    md5s = md5s + "key=" + keys
    # 计算签名是否一致，不一致返回错误
    if sign != util.md5(md5s).upper():
        return code_error
    # 检测订单是否一致
    out_trade_no = data['out_trade_no']['_text'].split('_')
    if len(out_trade_no) != 4:
        return code_error
    key = "machine_pay_data_" + datetime.datetime.today().strftime('%Y-%m-%d')
    result = redis.hget(key, data['out_trade_no']['_text'])
    result = eval(result)
    key1 = "car_wash_business_pay"
    data_push = {
        "wx_order": data['transaction_id']['_text'],
        "good_order": data['out_trade_no']['_text'],
        "pay_time": datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
        "order_time": result['orderTime'],
        "uid": out_trade_no[0],
        'suit_id': out_trade_no[1],
        "money": data['total_fee']['_text'],
    }
    redis.rpush(key1, data_push)
    return code_success


# 微信商家充值回调地址处理
def api_wx_business_recharge(data):
    data = xml2dict.xml2dict(data)
    # 支付状态失败，返回失败
    if data['result_code']['_text'] == "FAIL":
        return code_error
    # 验证APP_ID还有商户ID是否一致
    if app_id != data['appid']['_text'] or partner_id != data['mch_id']['_text']:
        return code_error
    params = {}
    sign = ''
    for xml in data:
        if xml == "sign":
            sign = data[xml]['_text']
        else:
            params[xml] = data[xml]['_text']
    # 检测是否含有签名
    if sign == '':
        return code_error
    params_keys = params.keys()
    params_keys.sort()
    md5s = ''
    for x in params_keys:
        md5s += x + "=" + params.get(x) + "&"
    md5s = md5s + "key=" + keys
    # 计算签名是否一致，不一致返回错误
    if sign != util.md5(md5s).upper():
        return code_error
    # 检测订单是否一致
    out_trade_no = data['out_trade_no']['_text'].split('_')
    if len(out_trade_no) != 4:
        return code_error
    key = "machine_pay_data_" + datetime.datetime.today().strftime('%Y-%m-%d')
    result = redis.hget(key, data['out_trade_no']['_text'])
    result = eval(result)
    key1 = "car_wash_business_recharge"
    data_push = {
        "wx_order": data['transaction_id']['_text'],
        "good_order": data['out_trade_no']['_text'],
        "pay_time": datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
        "order_time": result['orderTime'],
        "uid": out_trade_no[0],
        "money": data['total_fee']['_text'],
    }
    redis.rpush(key1, data_push)
    return code_success
